package com.blkj.iam.shared.sso.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.blkj.iam.common.result.Result;
import com.blkj.iam.common.util.DateUtils;
import com.blkj.iam.common.util.HttpSender;
import com.blkj.iam.shared.sso.bo.*;
import com.blkj.iam.system.model.entity.*;
import com.blkj.iam.system.service.*;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.sql.SQLIntegrityConstraintViolationException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @description: 数据迁移控制层
 * @author: Ethan
 * @create: 2025-04-24
 **/
@Tag(name = "数据迁移控制层")
@RestController
@RequestMapping("/api/v1/migrate")
@RequiredArgsConstructor
@Slf4j
public class MigrateController {

    private final DeptService deptService;
    private final UserService userService;
    private final RoleService roleService;
    private final UserRoleService userRoleService;
    private final MenuService menuService;
    private final RoleMenuService roleMenuService;
    private final PasswordEncoder passwordEncoder;


    @Operation(summary = "获取迁移数据")
    @GetMapping("/all")
    public Result<Object> migrateAll(int type) throws Exception {
        if (type == 0) {
            // 导入部门数据
            importDepart();
        } else if (type == 1) {
            // 导入用户数据
            importUser();
            importUserDept();
        } else if (type == 2) {
            // 导入角色数据
            importRole();
            importUserRole();
        } else if (type == 3) {
            importPermission();
            importRolePermission();
        }

        return Result.success();
    }

    @Operation(summary = "获取迁移数据")
    @GetMapping("/updateUser")
    public Result<Object> updateUser() {
        List<User> users = userService.list();
        for (User user : users) {
            userService.update(new LambdaUpdateWrapper<User>().eq(User::getId, user.getId()).set(User::getPassword, passwordEncoder.encode(user.getRawPass())));
        }
        return Result.success();
    }


    /***
     * 导入角色权限
     * @param
     * @return: void
     */
    private void importRolePermission() throws Exception {
        HttpSender sender = new HttpSender();
        String response = sender.get("http://localhost:8082/blkj/sys/api/migrate/rolePermission");
        JSONObject parseObj = JSONUtil.parseObj(response);
        JSONArray jsonArray = parseObj.getJSONArray("result");
        List<SysRolePermission> rolePermissionList = JSONUtil.toList(jsonArray, SysRolePermission.class);
        log.info("角色菜单总数：{}", rolePermissionList.size());
        int size = 1;
        for (SysRolePermission rolePermission : rolePermissionList) {
            Role role = roleService.getOne(new LambdaQueryWrapper<Role>().eq(Role::getIdStr, rolePermission.getRoleId()));
            Menu menu = menuService.getOne(new LambdaQueryWrapper<Menu>().eq(Menu::getIdStr, rolePermission.getPermissionId()));
            log.info("开始处理第{}个数据", size);

            if (ObjectUtil.isNotEmpty(role) && ObjectUtil.isNotEmpty(menu)) {
                RoleMenu ur = new RoleMenu();
                ur.setRoleId(role.getId());
                ur.setMenuId(menu.getId());
                ur.setTenantId(1L);
                try {
                    roleMenuService.save(ur);
                } catch (Exception e) {
                    if (e instanceof SQLIntegrityConstraintViolationException) {
                        log.warn("数据重复，跳过插入：roleId={}, menuId={}", ur.getRoleId(), ur.getMenuId());
                    } else {
                        log.error("插入数据失败，roleId={}, menuId={}, 异常信息：", ur.getRoleId(), ur.getMenuId(), e);
                    }
                }
            }
            size++;
        }
    }

    /***
     * 导入权限
     * @param
     * @return: void
     */
    private void importPermission() throws Exception {
        HttpSender sender = new HttpSender();
        String response = sender.get("http://localhost:8082/blkj/sys/api/migrate/permission");
        JSONObject parseObj = JSONUtil.parseObj(response);
        JSONArray jsonArray = parseObj.getJSONArray("result");
        List<SysPermission> permissionList = JSONUtil.toList(jsonArray, SysPermission.class);
        for (SysPermission permission : permissionList) {
            Menu menu = new Menu();
//            menu.setParentId();
            menu.setName(permission.getName());

            // 类型（0：一级菜单；1：子菜单 ；2：按钮权限）
            // 菜单类型(1-菜单；2-目录；3-外链；4-按钮权限)
            Integer menuType = permission.getMenuType();
            if (menuType == 0) {
                menu.setType(2);
            } else if (menuType == 1) {
                menu.setType(1);
                menu.setKeepAlive(1);
            } else if (menuType == 2) {
                menu.setType(4);
            }

            menu.setRouteName(permission.getUrl());
            menu.setRoutePath(permission.getUrl());
            menu.setComponent(permission.getComponent());
            menu.setPerm(permission.getPerms());
            menu.setPermType(permission.getPermsType());
            if (ObjectUtil.isNotEmpty(permission.getStatus())) {
                menu.setStatus(Integer.valueOf(permission.getStatus()));
            } else {
                menu.setStatus(1);
            }
            menu.setVisible(permission.isHidden() ? 0 : 1);
            menu.setSort(-1);
            menu.setRoute(permission.isRoute() ? 1 : 0);
            menu.setIcon(permission.getIcon());
            menu.setRedirect(permission.getRedirect());
//            menu.setTreePath();
            menu.setCreateTime(DateUtils.dateToLocalDateTime(permission.getCreateTime()));
            menu.setUpdateTime(DateUtils.dateToLocalDateTime(permission.getUpdateTime()));
            menu.setTenantId(1L);
            menu.setIdStr(permission.getId());
            menu.setParentIdStr(permission.getParentId());
            menu.setClientRoute(0);
            menuService.save(menu);
        }

        // 构建treePath
        List<Menu> menuList = menuService.list(new LambdaQueryWrapper<Menu>().isNotNull(Menu::getIdStr));
        log.info("总菜单数量：{}", menuList.size());
        int number = 1;
        for (Menu menu : menuList) {
            log.info("当前处理第{}个", number);
            String builtTreePath = buildMenuTreePath(menu);
            menuService.update(new LambdaUpdateWrapper<Menu>().eq(Menu::getId, menu.getId()).set(Menu::getTreePath, builtTreePath));
            if (number == menuList.size()) {
                break;
            }
            number++;
        }

        // 菜单排序
        List<Menu> menuSorList = menuService.list(new LambdaQueryWrapper<Menu>().isNotNull(Menu::getParentId).eq(Menu::getTenantId, 1L).groupBy(Menu::getParentId, Menu::getId));
        Map<Long, List<Menu>> listMap = menuSorList.stream().collect(Collectors.groupingBy(Menu::getParentId));
        listMap.forEach((k, v) -> {
            log.info("开始处理parentId为：{} 的数据", k);
            int sortNum = 1;
            for (Menu menu : v) {
                menuService.update(new LambdaUpdateWrapper<Menu>().eq(Menu::getId, menu.getId()).set(Menu::getSort, sortNum));
                sortNum++;
            }
        });
    }

    /***
     * 构建treePath
     * @param menu
     * @return: java.lang.String
     */
    public String buildMenuTreePath(Menu menu) {
        if (menu == null || ObjectUtil.isEmpty(menu.getParentIdStr())) {
            updateParentId(menu.getId(), 0L);
            return "0," + menu.getId().toString();
        }

        if (menu.getParentIdStr().equals(menu.getIdStr())) {
            return "0," + menu.getId().toString();
        }

        // 查询当前菜单的父菜单
        Menu parentMenu = menuService.getOne(new LambdaQueryWrapper<Menu>().eq(Menu::getIdStr, menu.getParentIdStr()));
        if (parentMenu == null) {
            return menu.getId().toString();
        }

        // 更新 parentId（在递归结束后统一更新）
        updateParentId(menu.getId(), parentMenu.getId());

        // 递归构建父菜单的 treePath
        String parentTreePath = buildMenuTreePath(parentMenu);

        // 构建当前菜单的 treePath
        return parentTreePath + "," + menu.getId().toString();
    }

    // 统一更新 parentId 的方法
    private void updateParentId(Long menuId, Long parentId) {
        menuService.update(new LambdaUpdateWrapper<Menu>().eq(Menu::getId, menuId).set(Menu::getParentId, parentId));
    }

    /***
     * 导入用户角色
     * @param
     * @return: void
     */
    private void importUserRole() throws Exception {
        HttpSender sender = new HttpSender();
        String response = sender.get("http://localhost:8082/blkj/sys/api/migrate/userRole");
        JSONObject parseObj = JSONUtil.parseObj(response);
        JSONArray jsonArray = parseObj.getJSONArray("result");
        List<SysUserRole> userRoleList = JSONUtil.toList(jsonArray, SysUserRole.class);
        for (SysUserRole userRole : userRoleList) {
            Role role = roleService.getOne(new LambdaQueryWrapper<Role>().eq(Role::getIdStr, userRole.getRoleId()));
            User user = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getIdStr, userRole.getUserId()));

            if (ObjectUtil.isNotEmpty(role) && ObjectUtil.isNotEmpty(user)) {
                UserRole ur = new UserRole();
                ur.setUserId(user.getId());
                ur.setRoleId(role.getId());
                ur.setTenantId(1L);
                userRoleService.save(ur);
            }
        }
    }

    /***
     * 导入部门用户关联关系
     * @param
     * @return: void
     */
    private void importUserDept() throws Exception {
        HttpSender sender = new HttpSender();
        String response = sender.get("http://localhost:8082/blkj/sys/api/migrate/departUser");
        JSONObject parseObj = JSONUtil.parseObj(response);
        JSONArray jsonArray = parseObj.getJSONArray("result");
        List<SysUserDepart> userDepartList = JSONUtil.toList(jsonArray, SysUserDepart.class);
        for (SysUserDepart userDepart : userDepartList) {
            Dept dept = deptService.getOne(new LambdaQueryWrapper<Dept>().eq(Dept::getIdStr, userDepart.getDepId()));
            User user = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getIdStr, userDepart.getUserId()));
            if (ObjectUtil.isNotEmpty(user) && ObjectUtil.isNotEmpty(dept)) {
                userService.update(new LambdaUpdateWrapper<User>().eq(User::getId, user.getId()).set(User::getDeptId, dept.getId()));
            }
        }
    }

    /***
     * 导入角色数据
     * @param
     * @return: void
     */
    private void importRole() throws Exception {
        HttpSender sender = new HttpSender();
        String response = sender.get("http://localhost:8082/blkj/sys/api/migrate/role");
        JSONObject parseObj = JSONUtil.parseObj(response);
        JSONArray jsonArray = parseObj.getJSONArray("result");
        List<SysRole> roleList = JSONUtil.toList(jsonArray, SysRole.class);
        Role serviceOne = roleService.getOne(new LambdaQueryWrapper<Role>().orderByDesc(Role::getSort).last("limit 1"));
        Integer sort = serviceOne.getSort();
        for (SysRole sysRole : roleList) {
            Role role = new Role();
            role.setName(sysRole.getRoleName());
            role.setCode(sysRole.getRoleCode());
            role.setSort(sort + 1);
            role.setStatus(1);
            role.setDataScope(1);
//            role.setCreateBy();
//            role.setUpdateBy();
            role.setIsDeleted(0);
            role.setTenantId(1L);
            role.setIdStr(sysRole.getId());
            role.setCreateTime(DateUtils.dateToLocalDateTime(sysRole.getCreateTime()));
            role.setUpdateTime(DateUtils.dateToLocalDateTime(sysRole.getUpdateTime()));
            role.setCreateUser(sysRole.getCreateBy());
            role.setUpdateUser(sysRole.getUpdateBy());
            role.setType(sysRole.getType());
            role.setItemType(sysRole.getItemType());
            role.setRoleType(sysRole.getRoleType());
            role.setDepartId(sysRole.getDepartId());
            role.setDepartName(sysRole.getDepartName());
            role.setSysOrgCode(sysRole.getSysOrgCode());
            role.setPtUserType(sysRole.getPtUserType());
            roleService.save(role);
            sort = role.getSort();
        }

        List<Role> list = roleService.list(new LambdaQueryWrapper<Role>().isNotNull(Role::getCreateUser));
        for (Role role : list) {
            String createUser = role.getCreateUser();
            User serviceTwo = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, createUser).eq(User::getTenantId, 1));
            if (ObjectUtil.isNotEmpty(serviceTwo)) {
                roleService.update(new LambdaUpdateWrapper<Role>().eq(Role::getId, role.getId()).set(Role::getCreateBy, serviceTwo.getId()));
            }

            String updateUser = role.getUpdateUser();
            User serviceThree = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, updateUser).eq(User::getTenantId, 1));
            if (ObjectUtil.isNotEmpty(serviceThree)) {
                roleService.update(new LambdaUpdateWrapper<Role>().eq(Role::getId, role.getId()).set(Role::getUpdateBy, serviceThree.getId()));
            }
        }
    }

    /***
     * 导入用户数据
     * @param
     * @return: void
     */
    private void importUser() throws Exception {
        HttpSender sender = new HttpSender();
        String response = sender.get("http://localhost:8082/blkj/sys/api/migrate/user");
        JSONObject parseObj = JSONUtil.parseObj(response);
        JSONArray jsonArray = parseObj.getJSONArray("result");
        List<SysUser> userList = JSONUtil.toList(jsonArray, SysUser.class);
        for (SysUser sysUser : userList) {
            User user = new User();
            user.setUsername(sysUser.getUsername());
            user.setNickname(sysUser.getRealname());
            user.setGender(sysUser.getSex());
            user.setPassword(passwordEncoder.encode(sysUser.getMwPass()));
            user.setRawPass(sysUser.getMwPass());
//            user.setDeptId();
            user.setTenantId(1L);
            user.setAvatar(sysUser.getAvatar());
            user.setMobile(sysUser.getPhone());
            if (sysUser.getStatus() == 1) {
                user.setStatus(1);
            } else {
                user.setStatus(0);
            }

            user.setEmail(sysUser.getEmail());
//            user.setCreateBy();
//            user.setUpdateBy();
            user.setCreateUser(sysUser.getCreateBy());
            user.setUpdateUser(sysUser.getUpdateBy());
            user.setIsDeleted(sysUser.getDelFlag());
            user.setUserType(sysUser.getUserType());
            user.setPersonType(sysUser.getPersonType());
            user.setMainType(sysUser.getMainType());
            user.setIdStr(sysUser.getId());
            user.setCreateTime(DateUtils.dateToLocalDateTime(sysUser.getCreateTime()));
            user.setUpdateTime(DateUtils.dateToLocalDateTime(sysUser.getUpdateTime()));
            user.setRemark(sysUser.getRemark());
            user.setLinkMan(sysUser.getLinkMan());
            userService.save(user);
        }

        // 更新部门数据
        List<Dept> deptList = deptService.list(new LambdaQueryWrapper<Dept>().isNotNull(Dept::getCreateUser));
        for (Dept dept : deptList) {
            String createUser = dept.getCreateUser();
            User serviceOne = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, createUser));
            if (ObjectUtil.isNotEmpty(serviceOne)) {
                deptService.update(new LambdaUpdateWrapper<Dept>().eq(Dept::getId, dept.getId()).set(Dept::getCreateBy, serviceOne.getId()));
            }

            String updateUser = dept.getUpdateUser();
            User serviceTwo = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, updateUser));
            if (ObjectUtil.isNotEmpty(serviceTwo)) {
                deptService.update(new LambdaUpdateWrapper<Dept>().eq(Dept::getId, dept.getId()).set(Dept::getUpdateBy, serviceTwo.getId()));
            }
        }

        // 更新用户数据
        List<User> users = userService.list(new LambdaQueryWrapper<User>().isNotNull(User::getCreateUser));
        for (User user : users) {
            String createUser = user.getCreateUser();
            User serviceOne = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, createUser));
            if (ObjectUtil.isNotEmpty(serviceOne)) {
                userService.update(new LambdaUpdateWrapper<User>().eq(User::getId, user.getId()).set(User::getCreateBy, serviceOne.getId()));
            }

            String updateUser = user.getUpdateUser();
            User serviceTwo = userService.getOne(new LambdaQueryWrapper<User>().eq(User::getUsername, updateUser));
            if (ObjectUtil.isNotEmpty(serviceTwo)) {
                userService.update(new LambdaUpdateWrapper<User>().eq(User::getId, user.getId()).set(User::getUpdateBy, serviceTwo.getId()));
            }
        }

    }

    /***
     * 导入部门数据
     * @param
     * @return: void
     */
    private void importDepart() throws Exception {
        HttpSender sender = new HttpSender();
        String response = sender.get("http://localhost:8082/blkj/sys/api/migrate/depart");
        JSONObject parseObj = JSONUtil.parseObj(response);
        JSONArray jsonArray = parseObj.getJSONArray("result");
        List<SysDepart> departList = JSONUtil.toList(jsonArray, SysDepart.class);
        Dept serviceOne = deptService.getOne(new LambdaQueryWrapper<Dept>().orderByDesc(Dept::getSort).last("limit 1"));
        Integer sort = serviceOne.getSort();
        for (SysDepart sysDepart : departList) {
            Dept depart = new Dept();
            depart.setName(sysDepart.getDepartName());
            depart.setCode(sysDepart.getOrgCode());
            depart.setNameAbbr(sysDepart.getDepartNameAbbr());
//            depart.setParentId();
//            depart.setTreePath();
            depart.setSort(sysDepart.getDepartOrder());
            depart.setIsDeleted(Integer.parseInt(sysDepart.getDelFlag()));
            if (depart.getIsDeleted() == 1) {
                depart.setStatus(0);
            } else {
                depart.setStatus(1);
            }
//            depart.setCreateBy();
//            depart.setUpdateBy();
            depart.setSort(sort + 1);
            depart.setCreateUser(sysDepart.getCreateBy());
            depart.setUpdateUser(sysDepart.getUpdateBy());
            depart.setCreateTime(DateUtils.dateToLocalDateTime(sysDepart.getCreateTime()));
            depart.setUpdateTime(DateUtils.dateToLocalDateTime(sysDepart.getUpdateTime()));
            depart.setTenantId(1L);
            depart.setIdStr(sysDepart.getId());
            depart.setParentIdStr(sysDepart.getParentId());
            depart.setDepartType(sysDepart.getDepartType());
            depart.setCustomOrgCode(sysDepart.getCustomOrgCode());
            depart.setGmType(sysDepart.getGmType());
            depart.setCountry(sysDepart.getCountry());
            depart.setLicenseFile(sysDepart.getLicenseFile());
            depart.setStorageContract(sysDepart.getStorageContract());
            depart.setTradeContract(sysDepart.getTradeContract());
            depart.setLinkMan(sysDepart.getLinkMan());
            depart.setLinkPhone(sysDepart.getPhone());
            depart.setLinkAccount(sysDepart.getMobile());
            depart.setMineCode(sysDepart.getMineCode());
            depart.setMgName(sysDepart.getMgName());
            depart.setAddress(sysDepart.getAddress());
            depart.setJgqIds(sysDepart.getJgqIds());
            depart.setJgType(sysDepart.getJgType());
            depart.setIdCard(sysDepart.getIdCard());
            deptService.save(depart);
        }

        // 构建treePath
        List<Dept> deptList = deptService.list(new LambdaQueryWrapper<Dept>().isNotNull(Dept::getIdStr));
        for (Dept dept : deptList) {
            String builtTreePath = buildTreePath(dept);
            deptService.update(new LambdaUpdateWrapper<Dept>().eq(Dept::getId, dept.getId()).set(Dept::getTreePath, builtTreePath));
        }
    }

    /***
     * 构建treePath
     * @param dept
     * @return: java.lang.String
     */
    public String buildTreePath(Dept dept) {
        if (dept == null || ObjectUtil.isEmpty(dept.getParentIdStr())) {
            return "0," + dept.getId().toString();
        }

        // 查询当前部门的父部门
        Dept parentDept = deptService.getOne(new LambdaQueryWrapper<Dept>().eq(Dept::getIdStr, dept.getParentIdStr()));
        if (parentDept == null) {
            return dept.getId().toString();
        }

        // 递归构建父部门的 treePath
        String parentTreePath = buildTreePath(parentDept);

        // 更新 parentId
        deptService.update(new LambdaUpdateWrapper<Dept>().eq(Dept::getId, dept.getId()).set(Dept::getParentId, parentDept.getId()));

        // 构建当前部门的 treePath
        return parentTreePath + "," + dept.getId().toString();
    }
}
